Daniel van Vugt [Thu, 29 Aug 2024 07:19:14 +0000 (15:19 +0800)]
shell/app: Warn instead of crashing if disposed before startup notification
This is currently easy to reproduce by launching and immediately closing
Chrome, then closing the shell. But automated crash reports show it can
also happen while using the shell, during a garbage collection run.
It's currently the top gnome-shell crasher in Ubuntu, and mostly with
Chromium/Electron apps. But regardless of the offender, we shouldn't
ever trust application behaviour to keep the shell alive.
search: Do not unregister a provider that was not registered
If the passed provider is not in this._providers, indexOf() returns -1 and
splice(-1, 1) silently removes the LAST provider in the array - an arbitrary,
unrelated provider.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/work_items/9317
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4308>
(cherry picked from commit a4c7d5e60e4f0982f7dfa048b7400eb4fdf2f97e)
environment: Extract transition completion handling into helper function
Add _setupTransitionCompletion to centralize started/stopped signal
handling and cleanup logic. Both _easeActor and _easeAnimatableProperty
now use this helper, reducing code duplication and ensuring consistent
behavior. The signal holder is created as a child of sessionSignalHolder
for proper cleanup on session shutdown.
environment: Keep cleanup symmetrical with prepare in ease functions
Add a guard to prevent cleanup() from running when prepare() was never
called. Currently cleanup() is called when "stopped" is emitted (which
ensures prepare() was called), in next commits cleanup will be called
from different events which means prepare() may not have been called.
unlockDialog: Wait for authPrompt destruction before switching VT
When switching to another user, wait until authPrompt is destroyed
and the clock transition animation completes before switching to
the login session VT.
The condition was checking for PROVIDE_USERNAME specifically, but
should also handle REUSE_USERNAME. Check for not DONT_PROVIDE_USERNAME
instead to correctly reuse the username when requested.
Andre Eikmeyer [Mon, 27 Jul 2026 11:57:25 +0000 (13:57 +0200)]
status/volume: Redundant volume pushes cause DSP crackling
Dragging the Quick Settings volume slider generates a dense sequence of
value notifications. After GVC rounds a requested value and scales the
channel map, several consecutive notifications can result in the same
effective channel volumes.
The shell currently assigns the value through the GObject property and
calls push_volume() unconditionally. The property setter discards the
boolean returned by gvc_mixer_stream_set_volume(), so unchanged values are
sent to the audio backend again.
This is audible with PipeWire DSP sinks. Volume changes pass through a
virtual filter sink and its processing graph before reaching the hardware
sink. The redundant pushes repeatedly update that control path while the
slider is moving, producing crackles. Native hardware sinks make the same
shell behavior much less apparent.
GNOME Settings does not show the problem because its volume slider calls
gvc_mixer_stream_set_volume() directly and only pushes the volume when the
effective channel map changed.
The Quick Settings slider now follows the same behavior and reuses the
returned change state for notification handling.
Daniel van Vugt [Wed, 15 Jul 2026 10:44:06 +0000 (18:44 +0800)]
magnifier: Avoid applying monitor scaling factors to the cursor twice
The mouse actor needs special consideration because it is not a child
of the _uiGroupClone being magnified. So it gets magnified separately
*and* already has its own scaling factor from the source actor
(actually from the display scaling factor).
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/work_items/9302
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4290>
(cherry picked from commit b258fed0671d0f73a0308d42ab0af820dfab62cf)
ibusManager: Avoid reusing a renewed cancellable across async calls
When the shared cancellable gets renewed, in-flight async requests can end up
using the wrong instance.
Pass a stable cancellable per operation so each request stays bound to the
cancellable it started with.
Alessandro Bono [Mon, 29 Jun 2026 11:16:40 +0000 (13:16 +0200)]
shell/global: Iterate over all leisure closures
The loop was using 'closures->data' instead of 'iter->data', causing
only the first leisure closure to be executed and freed on each cycle.
All subsequent closures in the list were leaked.
workspaceAnimation: Don't exclude minimized windows
We may be switching workspaces because we are focusing a window
that is located on a different workspace.
In case that new focus window was minimized, it currently just pops
up out of nowhere after the animation, as we are only tracking windows
that are visible at the beginning of the transition.
To fix this, don't exclude minimized windows from tracking, but hide
them until they are unminimized.
workspaceAnimation: Sort existing records when restacking
When restacking, we currently re-filter window actors, then match
each to the corresponding record.
Instead, sort the existing records according to the new stacking,
then iterate over those directly.
This reflects more directly that window records are fixed during
the transition, and avoids a (harmless) warning in case a window
only appeared during the animation and therefore cannot be
matched to a record.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/work_items/8881
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4199>
(cherry picked from commit e7e6de300cfb87c0f91738861b545017e5290ef9)
Florian Müllner [Fri, 29 May 2026 15:15:26 +0000 (17:15 +0200)]
keyboard: Fix menu animation
PopupMenu.open() takes a PopupAnimation flag, not a boolean. Due
to implicit type conversion, we are currently effectively passing
`PopupAnimation.SLIDE`, so we miss the fade part of the animation.
Florian Müllner [Mon, 11 May 2026 13:16:16 +0000 (15:16 +0200)]
style: Give notifications on lock screen the same width as in session
There is no strong reason to use the same width as user list and prompt
for notifications, in particular as the smaller width can make the
notification's content appear more cramped.
Instead, give notifications the same width as the message list in
the session. Especially where we reuse the same component — namely
media messages — this ensures consistent presentation.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/work_items/9218
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4217>
(cherry picked from commit 6b52520d9d0c3e8d918dd87bb2a04dc3122755a5)
Alessandro Bono [Fri, 19 Jun 2026 10:43:31 +0000 (12:43 +0200)]
shell/app: Plug GTask leak
The shell_app_activate_action() function gives ownership of the task
to activate_action_get_bus_cb(), which then transfers it to
on_activate_action_cb().
Alessandro Bono [Tue, 16 Jun 2026 08:47:10 +0000 (10:47 +0200)]
background: Handle promise rejection from _loadFile()
This suppresses the following:
```
(gnome-shell:11243): Gjs-WARNING **: 19:15:39.498: Unhandled promise rejection. To suppress
this warning, add an error handler to your promise chain with .catch() or a try-catch block
around your await expression. Stack trace of the failed promise:
_loadFile@resource:///org/gnome/shell/ui/background.js:501:20
_load@resource:///org/gnome/shell/ui/background.js:531:14
_init@resource:///org/gnome/shell/ui/background.js:288:14
Background@resource:///org/gnome/shell/ui/background.js:244:4
getBackground@resource:///org/gnome/shell/ui/background.js:635:30
_createBackgroundActor@resource:///org/gnome/shell/ui/background.js:807:49
_updateBackgroundActor@resource:///org/gnome/shell/ui/background.js:779:39
_createBackgroundActor/changeSignalId<@resource:///org/gnome/shell/ui/background.js:835:18
_emitChangedSignal/this._changedIdleId<@resource:///org/gnome/shell/ui/background.js:321:18
@resource:///org/gnome/shell/ui/init.js:21:20
```
Daniel van Vugt [Tue, 9 Jun 2026 07:44:39 +0000 (15:44 +0800)]
appDisplay: Clip the icon+label to allocation when expanding
It's hard to see at regular speed, but if you slow down the animation
then it becomes apparent the label was appearing outside the tile during
expansion. This keeps it clipped inside the expanding tile.
Andre Nijman [Mon, 8 Jun 2026 05:45:01 +0000 (13:45 +0800)]
workspace: Avoid redundant boundingBox copies in window layout
WorkspaceLayout's allocation reads child.boundingBox four times for each
window on every frame of an overview transition. The getter returns a
fresh copy of the cached box on every access, so this is four throwaway
objects per window per frame feeding the garbage collector.
Read the box into a local once and use that. The values are identical;
only the per-frame allocations go away.
Tony Chen [Tue, 2 Jun 2026 20:30:18 +0000 (16:30 -0400)]
workspaceAnimation: Block workspace updates during switch
WorkspaceAnimation uses a fixed set of workspace indices to transition
between for each gesture/animation.
That means that if workspaces change during the animation, the mapping
from workspace adjustment value to the animation progress can involve
invalid indices and the animation ends on the wrong workspace.
To fix this, block workspace updates during the animation.
authPrompt: Await wiggle via show-message promise resolver
Pass promise resolver through the show-message signal so the
message queue waits for the wiggle animation to finish before scheduling
the next message timeout. This replaces the previous approach of manually
increasing the timeout duration to account for the wiggle.
animationUtils: Skip no-op wiggle to avoid cancelling pending transitions
When wiggle() is called with duration 0, the async easeAsync calls
yield between microtasks, leaving pending operations that remove
transitions on the same property. This becomes a problem when two
setMessage() calls happen in the same call stack (e.g. via
_queuePriorityMessage): the first fires a no-op wiggle(dur:0) and
the second starts the real wiggle(dur:65). When microtasks drain,
the first wiggle's pending easeAsync calls overwrite the second
wiggle's active transition, effectively cancelling the real animation.
Return early when duration is 0, since the animation is a no-op anyway.
Fixes: fdadbb7a5a2 ("animationUtils: Use easeAsync() for wiggle") Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/work_items/9207
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4209>
When discussing goblint on Matrix, there were some concerns
around its rules for defining properties:
- having to explicitly track the last property ID, instead
of including N_PROPS in the anonymous enum
- including read-only properties in set() and write-only in get()
adds unreachable code, which is bad for code coverage
Those were considered more important than the benefit of checking
get()/set() with `-Wswitch-enum`, so at least for now stick with
the existing property conventions.
Add a configuration that enables "legacy" style for the corresponding
rules.
Sebastian Keller [Thu, 30 Apr 2026 01:44:57 +0000 (03:44 +0200)]
keyboardManager: Use layout id when reapplying
`_doApply()` expects the id rather than the layout info itself. Passing
the layout info caused the lookup to fail and the function to exit
early. This was preventing `xkb-option` or `xkb-model` settings from
applying when changed.
Fixes: 0f9034687 ("status/keyboard: Adapt to external source of keyboard layout") Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/work_items/9197
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4205>
Running tests and builds will sometimes create either a Python
`__pycache__` directory or a Meson `.wraplock` file. Probably a good
idea to ignore those so they never get included upstream.
Sebastian Keller [Mon, 27 Apr 2026 20:53:59 +0000 (22:53 +0200)]
messageTray: Don't try to focus destroyed actor
When `ungrabFocus()` is called after hiding a notification, the previous
focus actor might have already been destroyed and trying to focus it
will trigger a gjs error.
shell/app: Be extra careful when applying GPU environment
We get the environment from SwitcherooControl as an array of
key-value pairs. When applying it, we loop over the array in pairs,
assuming that every key has a value.
While this is the expected format, it does not hurt to be defensive
against possible bugs in the service, so explicitly check that both
key and value are non-NULL before applying them.
Milan Crha [Wed, 22 Apr 2026 15:04:28 +0000 (17:04 +0200)]
endSessionDialog: Recognize scheduled updates in the Power Off dialog
The Power Off dialog should show a checkbox to install (or not) a scheduled
update, but I missed it in my previous https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4185
animation: Prevent spinner animation from resetting
Currently, the search status spinner animation restarts on every
single keystroke while a search is in progress. This occurs because
redundant calls to `play()` replace the previous content and restart
the animation from the beginning.
This commit fixes this by ignoring redundant `play()` and `stop()` calls.
Sebastian Keller [Tue, 21 Apr 2026 11:59:51 +0000 (13:59 +0200)]
autorunManager: Connect to the correct notification signal
The signal is called `activated`. This was triggering an error and
preventing the notification from showing up when connecting an USB
drive with autorun enabled.
Milan Crha [Mon, 20 Apr 2026 10:22:48 +0000 (12:22 +0200)]
endSessionDialog: Prepare updates also in the "Restart & Install" dialog
The current code expects a checkbox to confirm update installation to be
present, but when the updates are already scheduled, it did not confirm
the actual user action for the update, aka to reboot the machine, instead
of using the previously set update action, which could be Power Off.
Milan Crha [Tue, 21 Apr 2026 15:38:10 +0000 (17:38 +0200)]
endSessionDialog: Differentiate between prepared and scheduled updates again
The prepared updates are those downloaded, while the scheduled updates
are those ready to be installed the next machine boot. The previous
gnome-software change with its OfflineUpdates D-Bus interface did not
count with it and claimed all the updates as scheduled, even when they
had been only prepared. This makes it work again by utilizing the
gnome-software changes.